package com.gitee.l0km.aocache;

import java.lang.reflect.Field;
import java.lang.reflect.Type;

import com.gitee.l0km.aocache.DataProtections.IdentityFilter;

public class AocacheTestUtils extends AocacheUtils {
	public static Type resolveType(Class<?> clazz, Type typeOfTarget) {
		return AocacheUtils.resolveType(clazz, typeOfTarget);
	}

	public static Type[] resolveType(Class<?> clazz, Type... typesOfTarget) {
		return AocacheUtils.resolveTypes(clazz, typesOfTarget);
	}

	public static Type resolveType(Object target, Type typeOfTarget) {
		return AocacheUtils.resolveType(target, typeOfTarget);
	}

	public static Type[] resolveType(Object target, Type... typesOfTarget) {
		return AocacheUtils.resolveTypes(target, typesOfTarget);
	}

	/**
	 * 断言两个字段是否符合预期。
	 * <p>
	 * 根据 {@link IdentityFilter} 的规则，判断两个字段是否相同或相等。
	 * <br>
	 * 如果 {@link IdentityFilter#identity(java.lang.reflect.Type)} 返回 true，则断言两个字段引用相同；
	 * 否则，断言两个字段引用不同且值相等。
	 * <p>
	 * @param identityFilter 用于判断字段是否应具有相同引用的过滤器。
	 * @param msg 断言失败时显示的自定义消息
	 * @param expected 期望的字段值
	 * @param actual 实际的字段值
	 * @param fieldType 字段的类型
	 * @param <T> 字段的类型
	 */
    public static <T> void assertField(IdentityFilter identityFilter, String msg, T expected, T actual, Type fieldType) {
		msg = null == msg ? "" : msg + ": ";
		if (identityFilter.identity(fieldType)) {
			/** assert same*/
			if (expected != actual) {
				throw new AssertionError(msg + "NOT SAME: expected:<" + expected + "> but was:<" + actual + ">");
			}
		} else {
			/** assert not same */
			if (expected == actual) {
				throw new AssertionError(msg + "SAME: expected:<" + expected + "> but was:<" + actual + ">");
			}
			/** assert equals */
			if (expected != null && !expected.equals(actual)) {
				throw new AssertionError(msg + "NOT EQUALS: expected:<" + expected + "> but was:<" + actual + ">");
			}
		}
	}
	public static <T> void assertField(IdentityFilter identityFilter, T expected, T actual, Type fieldType) {
		assertField(identityFilter, null, expected, actual, fieldType);
	}

	public static <T> void assertField(IdentityFilter identityFilter, String msg, T expected, T actual, Class<?> clazz, Type fieldType) {
		assertField(identityFilter, msg, expected, actual, resolveType(clazz, fieldType));
	}

	public static <T> void assertField(IdentityFilter identityFilter, T expected, T actual, Class<?> clazz, Type fieldType) {
		assertField(identityFilter, null, expected, actual, resolveType(clazz, fieldType));
	}

	public static <T> void assertField(IdentityFilter identityFilter, T expected, T actual, Field field) {
		assertField(identityFilter, field.getName(), expected, actual, resolveType(field.getDeclaringClass(), field.getGenericType()));
	}
}
